﻿using System;
using System.Collections.Generic;

using DigitalQuran.Data.Metadata;

namespace DigitalQuran.Collection
{
    /// <summary>
    /// Collection of <see cref="DigitalQuran.Chapter"/>
    /// </summary>
    public class ChapterCollection : ReadOnlyCollection<Chapter>
    {
        /// <summary>
        /// Total Chapters in Qur'an
        /// </summary>
        public const int TotalChapters = 114;

        internal ChapterCollection() : this(0, TotalChapters) { }

        /// <summary>
        /// Craetes new Subset of <see cref="DigitalQuran.Collection.ChapterCollection"/>
        /// </summary>
        /// <param name="startIndex">First Chapter Index</param>
        /// <param name="count">Total Chapters to include</param>
        public ChapterCollection(int startIndex, int count)
            : base(count)
        {
            this.startIndex = startIndex;
        }

        int startIndex = 0;
        public override Chapter this[int index]
        {
            get
            {
                if (index < Count)
                    return _Chapters[index + startIndex];
                else
                    throw new IndexOutOfRangeException();
            }
        }

        public override IEnumerator<Chapter> GetEnumerator()
        {
            for (int i = 0; i < Count; i++)
            {
                yield return _Chapters[i + startIndex];
            }
        }

        static Chapter[] _ChronologicalChapters = null;
        /// <summary>
        /// Gets Array of Chapters Arranged in Chronological Order
        /// </summary>
        public static Chapter[] ChronologicalChapters
        {
            get
            {
                if (_ChronologicalChapters == null)
                {
                    _ChronologicalChapters = new Chapter[TotalChapters];
                    
                    foreach (var ch in _Chapters)
                    {
                        _ChronologicalChapters[ch.RevelationOrder - 1] = ch;
                    }
                }

                return _ChronologicalChapters;
            }
        }

        /// <summary>
        /// Gets <see cref="DigitalQuran.Chapter"/> from Verse ID
        /// </summary>
        /// <param name="verseId">Verse ID</param>
        /// <returns>Returns <see cref="DigitalQuran.Chapter"/> if valid verse id else returns null</returns>
        public static Chapter GetChaperFromVerseId(int verseId)
        {
            verseId++;
            for (int i = 1; i < TotalChapters; i++)
                if (_Chapters[i].FirstVerse.GlobalNumber < verseId)
                    return _Chapters[i - 1];

            return null;
        }

        static Chapter[] _Chapters = new Chapter[TotalChapters];
        internal static void LoadData(IEnumerator<ChapterMeta> e)
        {
            for (int i = 0; i < TotalChapters; i++)
            {
                e.MoveNext();
                _Chapters[i] = new Chapter(i, e.Current);
            }
        }
    }

    /// <summary>
    /// Extended Collection of <see cref="DigitalQuran.Chapter"/>
    /// </summary>
    public class ChapterCollectionEx : ChapterCollection {

        /// <summary>
        /// Create new instance
        /// </summary>
        /// <param name="indexes">List of chapter indexes to include in collection</param>
        public ChapterCollectionEx(List<int> indexes)
            : base(0, VerseCollection.TotalVerses) {
            this.indexes = indexes;
        }

        List<int> indexes;

        public override Chapter this[int index] {
            get {
                return base[indexes[index]];
            }
        }

        public override IEnumerator<Chapter> GetEnumerator() {
            foreach (var index in indexes) {
                yield return base[index];
            }
        }
    }
}